package com.atwisdom.star.thirdInterface.business;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.atwisdom.star.common.actionType.InfConfigActionType;
import com.atwisdom.star.common.vo.ActionData;
import com.atwisdom.star.common.vo.ResultInfo;
import com.atwisdom.star.exception.pojo.BusinessException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public abstract class BaseInfDslService<T> {

    @Transactional
    public ResultInfo<?> responseFactory(List<ActionData<JSONObject>> actionDataList) throws BusinessException {
        ResultInfo<?> resultInfo = null;
        for (ActionData<JSONObject> actionData : actionDataList) {
            String action = actionData.getAction();
            InfConfigActionType actionType = InfConfigActionType.valueOf(action);
            String methodName = actionType.getMethodName();
            resultInfo = this.execMethod(methodName, actionData);
        }
        return resultInfo;
    }

    /**
     * 反射执行业务方法
     *
     * @param methodName 方法名
     * @param actionData 方法参数
     * @return 返回结果
     * @throws BusinessException 业务异常
     */
    public abstract ResultInfo<?> execMethod(String methodName, ActionData<JSONObject> actionData) throws BusinessException;

    /**
     * 构造查询对象
     * @param actionData 参数
     * @return 返回结果
     */
    public QueryWrapper<T> buildQueryWrapper(ActionData<JSONObject> actionData) {
        return this.buildQueryWrapper(actionData,true);
    }

    /**
     * 构造查询对象
     * @param actionData 参数
     * @return 返回结果
     */
    public QueryWrapper<T> buildQueryWrapper(ActionData<JSONObject> actionData,boolean hasPublished ) {
        String condition = actionData.getCondition();
        String className = actionData.getClassName();
        BigDecimal version = actionData.getVersion();
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(actionData.getId()!=null, "id", actionData.getId());
        queryWrapper.eq(StringUtils.isNotBlank(actionData.getType()), "type", actionData.getType());
        queryWrapper.eq(StringUtils.isNotBlank(className), "className", className);
        queryWrapper.eq(version!=null, "version", version);
        queryWrapper.in(CollectionUtil.isNotEmpty(actionData.getIds()), "id", actionData.getIds());
        if(hasPublished){
            queryWrapper.eq("published", 1);
        }
        if(StringUtils.isNotBlank(condition)){
            condition = this.transformOperator(condition);
            queryWrapper.apply(condition);
        }
        return queryWrapper;
    }

    public QueryWrapper<T> buildOrderBy(QueryWrapper<T> queryWrapper,String orderBy,String defaultOrderBy ) {
        Map<String, List<String>> orderByMap = new HashMap<>();
        if(StringUtils.isNotBlank(orderBy)){
            List<String> orderList =  Arrays.asList(orderBy.split(";"));
            orderList.forEach(o -> {
                if (o.indexOf("asc") > 0) {
                    o.replaceAll(",asc", "");
                    List<String> ascList = Arrays.asList(o.split(","));
                    orderByMap.put("asc", ascList);
                } else if (o.indexOf("desc") > 0) {
                    o.replaceAll(",desc", "");
                    List<String> descList = Arrays.asList(o.split(","));
                    orderByMap.put("asc", descList);
                }
            });
        }
        if (orderByMap.size() > 0) {
            for (String key : orderByMap.keySet()) {
                if (key.equalsIgnoreCase("desc")) {
                    queryWrapper.orderByDesc(orderByMap.get(key));
                } else {
                    queryWrapper.orderByAsc(orderByMap.get(key));
                }
            }
        } else {
            List<String> columns = Arrays.asList(defaultOrderBy.split(","));
            queryWrapper.orderByDesc(columns);
        }
        return queryWrapper;
    }

    /**
     * 是否有效删除
     * @param actionData 参数
     * @return
     */
    public boolean validActionData(ActionData actionData){
        String condition = actionData.getCondition();
        String className = actionData.getClassName();
        List<Long> ids = actionData.getIds();
        if (actionData.getId()==null && StringUtils.isBlank(actionData.getType()) && StringUtils.isBlank(className) && StringUtils.isBlank(condition) && (ids==null || ids.size() <1 ) ) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 操作符转换
     *
     * @param condition 转换参数
     */
    public String transformOperator(String condition) {
        Map<String, String> operatorType = this.getOperatorType();
        for (Map.Entry<String, String> entry : operatorType.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            condition = condition.replaceAll(key, value);
        }
        return condition;
    }

    /**
     * 数学操作符与sql操作符映射
     * @return 返回操作数据
     */
    public Map<String, String> getOperatorType() {
        Map<String, String> operatorMap = new HashMap<>();
        operatorMap.put("==", " = ");
        operatorMap.put("!=", " <> ");
        operatorMap.put("≠", " <> ");
        operatorMap.put("≥", " >= ");
        operatorMap.put("≤", " <= ");

        operatorMap.put("&&", " AND ");
        operatorMap.put("\\|\\|", " OR ");
        operatorMap.put("!", " NOT ");
        return operatorMap;
    }
}
